package com.github.syncrepo;

import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHPermissionType;

import java.io.Console;
import java.util.Scanner;

/**
 * Token validation utility to verify GitHub token and permissions
 * 
 * NOTE: This tool is specifically designed for GitHub API validation.
 * For GitCode or GitLab, you can still use the main sync tool directly.
 * This validator uses GitHub's REST API and may not work with other platforms.
 */
public class TokenValidator {

    public static void main(String[] args) {
        System.out.println("\n========================================");
        System.out.println("GitHub Token 验证工具 (GitHub Only)");
        System.out.println("========================================\n");

        String token = getTokenFromUser();
        
        if (token == null || token.trim().isEmpty()) {
            System.err.println("✗ Token不能为空！");
            System.exit(1);
        }

        System.out.println("开始验证Token...\n");

        // Test 1: Basic token validity
        System.out.println("【测试 1/3】验证Token基本有效性...");
        GitHub github = testTokenValidity(token);
        if (github == null) {
            System.exit(1);
        }

        // Test 2: Check permissions
        System.out.println("\n【测试 2/3】检查Token权限...");
        checkTokenPermissions(github);

        // Test 3: Test specific repository access
        System.out.println("\n【测试 3/3】测试目标仓库访问权限...");
        testRepositoryAccess(github);

        System.out.println("\n========================================");
        System.out.println("✓ 所有测试完成！");
        System.out.println("========================================\n");
    }

    private static String getTokenFromUser() {
        if (System.getenv("GITHUB_TOKEN") != null) {
            System.out.println("检测到环境变量 GITHUB_TOKEN");
            return System.getenv("GITHUB_TOKEN");
        }

        Console console = System.console();
        if (console != null) {
            char[] tokenChars = console.readPassword("请输入GitHub Token (输入将被隐藏): ");
            return new String(tokenChars);
        } else {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入GitHub Token: ");
            return scanner.nextLine().trim();
        }
    }

    private static GitHub testTokenValidity(String token) {
        try {
            GitHub github = new GitHubBuilder().withOAuthToken(token).build();
            
            // Test if we can get user info
            String login = github.getMyself().getLogin();
            String name = github.getMyself().getName();
            
            System.out.println("  ✓ Token有效！");
            System.out.println("  用户名: " + login);
            if (name != null && !name.isEmpty()) {
                System.out.println("  姓名: " + name);
            }
            System.out.println("  Token格式: " + maskToken(token));
            
            return github;
            
        } catch (Exception e) {
            System.err.println("  ✗ Token验证失败！");
            System.err.println("  错误: " + e.getMessage());
            System.err.println("\n  可能的原因:");
            System.err.println("    1. Token格式不正确");
            System.err.println("    2. Token已过期");
            System.err.println("    3. Token已被撤销");
            System.err.println("\n  解决方案:");
            System.err.println("    访问 https://github.com/settings/tokens");
            System.err.println("    生成一个新的Token");
            return null;
        }
    }

    private static void checkTokenPermissions(GitHub github) {
        try {
            // Check OAuth scopes
            String rateLimit = "Rate Limit: " + github.getRateLimit().getRemaining() + "/" + 
                             github.getRateLimit().getLimit();
            System.out.println("  " + rateLimit);
            
            // Try to list repositories (requires repo scope)
            System.out.println("\n  检查 'repo' 权限...");
            try {
                github.getMyself().listRepositories().iterator().hasNext();
                System.out.println("  ✓ Token具有仓库访问权限");
            } catch (Exception e) {
                System.err.println("  ✗ Token缺少 'repo' 权限！");
                System.err.println("    这是最常见的问题！");
                System.err.println("\n  解决方案:");
                System.err.println("    1. 访问 https://github.com/settings/tokens");
                System.err.println("    2. 编辑现有Token或创建新Token");
                System.err.println("    3. 确保勾选: ☑ repo (Full control of private repositories)");
                return;
            }

            System.out.println("\n  Token权限检查通过！");
            
        } catch (Exception e) {
            System.err.println("  ✗ 权限检查失败: " + e.getMessage());
        }
    }

    private static void testRepositoryAccess(GitHub github) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("\n  输入要测试的仓库 (格式: username/repository): ");
        String repoName = scanner.nextLine().trim();
        
        if (repoName.isEmpty()) {
            System.out.println("  跳过仓库访问测试");
            return;
        }

        try {
            System.out.println("\n  正在检查仓库: " + repoName);
            GHRepository repo = github.getRepository(repoName);
            
            System.out.println("  ✓ 可以访问仓库");
            System.out.println("    仓库名称: " + repo.getFullName());
            System.out.println("    仓库描述: " + (repo.getDescription() != null ? repo.getDescription() : "无"));
            System.out.println("    是否私有: " + (repo.isPrivate() ? "是" : "否"));
            System.out.println("    默认分支: " + repo.getDefaultBranch());
            
            // Check permissions
            System.out.println("\n  检查仓库权限...");
            
            try {
                GHPermissionType permission = repo.getPermission(github.getMyself().getLogin());
                System.out.println("  您的权限: " + permission);
                
                boolean canPush = permission == GHPermissionType.ADMIN || 
                                permission == GHPermissionType.WRITE;
                
                if (canPush) {
                    System.out.println("  ✓ 具有推送权限 (PUSH)");
                    System.out.println("\n  ✓✓✓ 该Token可以用于同步到这个仓库！");
                } else {
                    System.err.println("  ✗ 没有推送权限 (需要 WRITE 或 ADMIN)");
                    System.err.println("    当前权限: " + permission);
                    System.err.println("\n  解决方案:");
                    System.err.println("    1. 确保您是仓库的管理员或协作者");
                    System.err.println("    2. 访问仓库 Settings → Manage Access");
                    System.err.println("    3. 添加您的账户为协作者");
                }
            } catch (Exception e) {
                // Some repos don't expose permission info
                System.out.println("  无法获取详细权限信息");
                System.out.println("  提示: 如果这是您自己的仓库，应该有推送权限");
            }
            
        } catch (org.kohsuke.github.GHFileNotFoundException e) {
            System.err.println("  ✗ 仓库不存在或无权访问");
            System.err.println("    请检查仓库名称是否正确");
        } catch (Exception e) {
            System.err.println("  ✗ 访问仓库失败: " + e.getMessage());
            if (e.getMessage().contains("404")) {
                System.err.println("    仓库不存在或您没有访问权限");
            }
        }
    }

    private static String maskToken(String token) {
        if (token == null || token.length() < 10) {
            return "****";
        }
        return token.substring(0, 7) + "..." + token.substring(token.length() - 4);
    }
}

